package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.autoconfig.exceptor.BusinessException;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.domain.Question;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.dto.RecommendUserDto;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.vo.*;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class TanhuaService {

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionApi questionApi;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private HuanXinTemplate template;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${tanhua.default.recommend.users}")
    private String recommendUser;

    @Autowired
    private MessagesService messagesService;

    @DubboReference
    private UserLikeApi userLikeApi;

    @DubboReference
    private UserLocationApi userLocationApi;

    @DubboReference
    private VisitorsApi visitorsApi;



    //查询今日佳人数据
    public TodayBest todayBest() {
        //1、获取用户id
        Long toUserId = UserHolder.getUserId();
        //2、调用API查询
        RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(toUserId);
        if(recommendUser == null) {
            recommendUser = new RecommendUser();
            recommendUser.setUserId(1l);
            recommendUser.setScore(99d);
        }
        //3、将RecommendUser转化为TodayBest对象
        Long userId = recommendUser.getUserId();
        UserInfo userInfo = userInfoService.findUserInfoById(userId);
        TodayBest todayBest = TodayBest.init(userInfo, recommendUser);
        return todayBest;

     }


    //查询分页推荐好友列表
    public PageResult recommendation(RecommendUserDto dto) {
        //1 获取用户id
        Long toUserId = UserHolder.getUserId();

        //2 调用recommendUserApi分页查询数据列表
        PageResult pr = recommendUserApi.queryRecommendUserList(dto.getPage(),dto.getPagesize(),toUserId);

        //3 获取分页中的RecommendUser 数据列表
        List<RecommendUser> items = (List<RecommendUser>) pr.getItems();

        //4 判断列表是否为空
        if (items == null || items.size() <= 0) {
            return pr;
        }

        //5 提取所有推荐的用户id 列表
        List<Long> ids = CollUtil.getFieldValues(items, "userId", Long.class);
        UserInfo userInfo = new UserInfo();
        userInfo.setAge(dto.getAge());
        userInfo.setGender(dto.getGender());

        //6 构建查询条件 批量查询所有用户详情
        Map<Long,UserInfo> map = userInfoApi.findByIds(ids,userInfo);

        //7 循环推荐到数据列表 构建vo对象
        //
        List<TodayBest> list = new ArrayList<>();
        for (RecommendUser item : items) {
            UserInfo info = map.get(item.getUserId());
            if (info != null){
                TodayBest vo = TodayBest.init(info,item);
                list.add(vo);
            }
        }

        //8 构造返回值
        pr.setItems(list);
        return pr;
    }

    /**
     * 查看佳人详情
     * */
    public TodayBest personalInfo(Long userId) {
        // 根据 用户id查询 用户详情
        UserInfo userInfo = userInfoApi.findById(userId);

        // 根据操作人id 和查看的用户id 查看两者的推荐数据
        RecommendUser user = recommendUserApi.queryByUserId(userId,UserHolder.getUserId());

        /*Visitors visitors = new Visitors();
        visitors.setUserId(userId);
        visitors.setVisitorUserId(UserHolder.getUserId());
        visitors.setFrom("首页");
        visitors.setDate(System.currentTimeMillis());
        visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        visitors.setScore(user.getScore());*/
        /*
        * 保存访问记录到数据库
        * */
        visitorsApi.saveVisitor(userId,UserHolder.getUserId(),"首页");

        // 构造返回值
        return TodayBest.init(userInfo,user);
    }

    /**
     * 查看陌生人问题
     * */
    public String strangerQuestions(Long userId) {
        Question question = questionApi.findByUserId(userId);
        return question == null? "你是什么牛马？" : question.getTxt();
    }

    /**
     * 回复陌生人问题
     * */
    public void replyQuestions(Long userId, String reply) {
        // 构造消息数据
        Long currentUserId = UserHolder.getUserId();
        UserInfoVo userInfo = userInfoService.findById(userId);

        Map map = new HashMap();
        map.put("userId",currentUserId);
        map.put("huanXinId", Constants.HX_USER_PREFIX+currentUserId);
        map.put("nickname",userInfo.getNickname());
        map.put("strangerQuestion",strangerQuestions(userId));
        map.put("reply",reply);
        String message = JSON.toJSONString(map);

        Boolean aBoolean = template.sendMsg(Constants.HX_USER_PREFIX + userId, message);//1 接受方环信id 2 消息
        if (!aBoolean){
            throw new BusinessException(ErrorResult.error());
        }
    }

    /**
     * 探花 推荐用户列表
     * */
    public List<TodayBest> queryCardsList() {
       // 查询推荐数据列表 （排除 喜欢、不喜欢的用户 数量限制
        List<RecommendUser> users = recommendUserApi.queryCardsList(UserHolder.getUserId(), 10);

        //判断数据是否存在 如果不存在 构造默认数据
        if (CollUtil.isEmpty(users)){
            users = new ArrayList<>();
            String[] userIds = recommendUser.split(",");
            for (String userId : userIds) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(Convert.toLong(userId));
                recommendUser.setToUserId(UserHolder.getUserId());
                recommendUser.setScore(RandomUtil.randomDouble(60,90));
                users.add(recommendUser);
            }
        }

        //构造vo对象
        List<Long> ids = CollUtil.getFieldValues(users, "userId", Long.class);
        Map<Long, UserInfo> infoMap = userInfoApi.findByIds(ids, null);

        ArrayList<TodayBest> vos = new ArrayList<>();
        for (RecommendUser user : users) {
            UserInfo userInfo = infoMap.get(user.getUserId());
            if (userInfo!= null){
                TodayBest vo = TodayBest.init(userInfo, user);
                vos.add(vo  );
            }
        }
        return vos;
    }

    /**
     * 喜欢*/
    public void likeUser(Long likeUserId) {
        // 保存喜欢数据到  数据库
        Boolean aBoolean = userLikeApi.saveOrUpdate(UserHolder.getUserId(), likeUserId, true);
        if (!aBoolean){
            // 失败
            throw new BusinessException(ErrorResult.error());
        }

        //将喜欢数据写入redis 删除不喜欢的数据
        redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());

        Boolean like = isLike(likeUserId, UserHolder.getUserId());
        // 判断是否双向喜欢
         if (like){
            // 添加好友
            messagesService.contacts(likeUserId);
        }

    }

    /**
     * 不喜欢*/
    public void notLikeUser(Long likeUserId) {
        // 保存 不喜欢数据到 数据库
        Boolean save = userLikeApi.saveOrUpdate(UserHolder.getUserId(),likeUserId,false);
        if (!save){
            throw new BusinessException(ErrorResult.error());
        }

        //写入 不喜欢数据 到redis 删除喜欢的数据
        redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());
        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());

        // 删除好友
//        messagesService.removeContacts(likeUserId);
    }

    public Boolean isLike(Long userId, Long likeUserId){
        String key = Constants.USER_LIKE_KEY+userId;
        return redisTemplate.opsForSet().isMember(key,likeUserId.toString());
    }


    /**
     * 搜附近*/
    public List<NearUserVo> queryNearUser(String gender, String distance) {
        // 调用api查询附近用户
        List<Long> userIds = userLocationApi.queryNearUser(UserHolder.getUserId(),Double.valueOf(distance)  );

        // 判断集合是否为空
        if (CollUtil.isEmpty(userIds)){
            return new ArrayList<>();
        }

        // 调用userInfoApi 根据用户id 查询用户详情
        UserInfo userInfo = new UserInfo();
        userInfo.setGender(gender);
        Map<Long,UserInfo> map = userInfoApi.findByIds(userIds,userInfo);

        // 构造返回值
        List<NearUserVo> vos = new ArrayList<>();
        for (Long userId : userIds) {
            if (userId == UserHolder.getUserId()){
                continue;
            }
            UserInfo info = map.get(userId);
            if (info != null){
                NearUserVo vo = NearUserVo.init(info);
                vos.add(vo);
            }
        }
        return vos;
    }















}
